package inutan.gateway.action;

import bright.serialization.ByteBuf;
import inutan.common.constant.ModuleConstant;
import inutan.common.inner.protocol.InnerMessage;
import inutan.gateway.session.user.UserSession;
import inutan.gateway.session.user.UserSessions;
import luban.common.Command;
import luban.inner.LogicModular;
import luban.room.ResRoomInfo;
import org.ricks.common.lang.Logger;
import org.ricks.net.AioSession;
import org.ricks.net.Router;
import org.ricks.net.SessionManager;
import org.ricks.net.balancer.IConsumerLoadBalancer;
import org.ricks.net.rpc.AskPackage;
import org.ricks.net.rpc.Consumer;
import java.util.Objects;

public class GatewayHandler {

    /**
     * @param msg
     * @param userSession
     */
    public static void login(InnerMessage msg, UserSession userSession) {
        //登录游戏服
        loginGame(msg, userSession);
        //登录房间匹配服
    }

    /**
     * 网关rpc登录游戏服，登录成功绑定userId 玩家游戏唯一标识
     * @param msg
     * @param userSession
     */
    public static void loginGame(InnerMessage msg, UserSession userSession) {
        AioSession gameSession = getLogicSession(userSession, ModuleConstant.GAME_MODULE);
//        AskPackage askPackage = AskPackage.valueOf(gameSession.nextReqId(),Command.Login, msg.data);
//        Router.me().syncAsk(gameSession, askPackage, rpcPackage -> {
//            LongValue userId = LongValue.deserializeLongValue(new ByteBuf(rpcPackage.getPacket()));
//            Logger.info("userId: "+userId+"  login success & start bind sessionId:"+gameSession.sid());
//            /**  userSessionId <-> userId 绑定成功才是登录成功,只有绑定成功才能多人广播 */
//            UserSessions.me().settingUserId(gameSession.sid(),userId.value);
//        });
        Router.me().send(gameSession, msg);
    }


    /**
     * @param modularId 模块唯一标识 获取logicSession ,如果userSession未绑定 logicSession 则规则分配 然后加入绑定
     * @return
     */
    public static AioSession getLogicSession(UserSession userSession, byte modularId) {
        AioSession logicSession = userSession.getLogicSession(modularId);
        if(Objects.nonNull(logicSession)) {
            //断线重连 或则 5分钟心跳未超时 UserSession没有销毁
            return logicSession;
        }
        //
        IConsumerLoadBalancer consumerLoadBalancer =  Consumer.me().loadBalancer(modularId);
        logicSession = consumerLoadBalancer.loadBalancer(modularId , userSession);
        if(Objects.isNull(logicSession)) {
            throw new RuntimeException("玩家登录失败不能正确分配logicSession  , kcpSession["+userSession.getAioSession()+"] ,  modularId["+modularId+"] ");
        }
        //用户绑定逻辑节点
        userSession.addLogicSession(modularId, logicSession);

        return logicSession;
    }

    /**
     * 触发createSession事件向连上来的业务节点询问 标识
     */
    public static void askLogicMark(AioSession session) {
        AskPackage askPackage = AskPackage.valueOf(session.nextReqId(),30000, new byte[0]);
        Router.me().syncAsk(session, askPackage, rpcPackage -> {
            LogicModular logicModular = LogicModular.deserializeLogicModular(new ByteBuf(rpcPackage.getPacket()));
            Logger.info("Rpc Logic AskLogicMark  modularId:"+ logicModular.modularId );
            //rpc 拿到logic节点 模块标识信息，加入分组
            SessionManager.me().join(String.valueOf(logicModular.modularId) , session);
        });
    }

    /**
     * kcp心跳超时，驱动游戏服数据落地 清除缓存
     */
    public static void userExit(UserSession userSession, InnerMessage message) {
        AioSession gameSession = getLogicSession(userSession, ModuleConstant.GAME_MODULE);
        AskPackage askPackage = AskPackage.valueOf(gameSession.nextReqId(),Command.CreateRoom, message.data);
        Router.me().syncAsk(gameSession, askPackage, rpcPackage -> {
            ResRoomInfo resRoomInfo = ResRoomInfo.deserializeResRoomInfo(new ByteBuf(message.data));
            String roomId = resRoomInfo.roomType + "-" + resRoomInfo.roomId;
            UserSessions.me().join(roomId, userSession);
        });
    }
}
